﻿// owner 蒋家伟

#pragma once
// std
#include <functional>

// jsdk
#include "Correspond_home.h"
#include "BitoperationUtils.h"

namespace jsdk
{
    class IDataDecodec;
    using DataDecodecCreatorFunc = std::function<OwnerPtr<IDataDecodec>(void)>;

    class CORRESPOND_EXPORT DataDecodecRegisterUtils
    {
        template<typename> friend class DataDecodecRegisterHelper;
    public:
        /// \ brief 将传入的多个char拼接字符流
        template<char...>
        static std::string getAgreementString_Char()
        {
            std::vector<char> res;
            CharAgreementHead_Traits<args...>::get(res);
            return std::string(res.data(), res.size());
        }

        /// \ brief 将传入的整形数据拼接成字节流
        template<int...>
        static std::string getAgreementString_Int()
        {
            std::vector<char> res;
            IntAgreementHead_Traits<args...>::get(res);
            return std::string(res.data(), res.size());
        }

    private:
        template<int...>
        struct IntAgreementHead_Traits
        {
        };

        template<int code>
        struct IntAgreementHead_Traits<code>
        {
            static void get(std::vector<char>& res)
            {
                res.push_back(static_cast<int8_t>(getIndexSectionValue<24,31>(code)));
                res.push_back(static_cast<int8_t>(getIndexSectionValue<16, 23>(code)));
                res.push_back(static_cast<int8_t>(getIndexSectionValue<8, 15>(code)));
                res.push_back(static_cast<int8_t>(getIndexSectionValue<0, 7>(code)));
                return;
            }
        };

        template<int code, int... args>
        struct IntAgreementHead_Traits<code, args...>
        {
            static void get(std::vector<char>& res)
            {
                res.push_back(static_cast<int8_t>(getIndexSectionValue<24, 31>(code)));
                res.push_back(static_cast<int8_t>(getIndexSectionValue<16, 23>(code)));
                res.push_back(static_cast<int8_t>(getIndexSectionValue<8, 15>(code)));
                res.push_back(static_cast<int8_t>(getIndexSectionValue<0, 7>(code)));
                return IntAgreementHead_Traits<args...>::get(res);
            }
        };

        template<char...>
        struct CharAgreementHead_Traits
        {
        };

        template<char code>
        struct CharAgreementHead_Traits<code>
        {
            static void get(std::vector<char>& res)
            {
                res.push_back(code);
                return;
            }
        };

        template<char code, char... args>
        struct CharAgreementHead_Traits<code, args...>
        {
            static void get(std::vector<char>& res)
            {
                res.push_back(code);
                return CharAgreementHead_Traits<args...>::get(res);
            }
        };

        static bool registerCreator(const std::string& agreementHead, DataDecodecCreatorFunc func);
    };
}

